// addrspace.h 
//	Data structures to keep track of executing user programs 
//	(address spaces).
//
//	For now, we don't keep any information about address spaces.
//	The user level CPU state is saved and restored in the thread
//	executing the user program (see thread.h).
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef ADDRSPACE_H
#define ADDRSPACE_H

#include "copyright.h"
#include "../filesys/filesys.h"
#include "table.h"
#include "../machine/translate.h"


#define UserStackSize		1024 	// increase this as necessary!
#ifdef CHANGED
#define MAX_NUMBER_OF_THREADS 50
#endif
#define MaxOpenFiles 256
#define MaxChildSpaces 256

class AddrSpace {
  public:
    AddrSpace(OpenFile *executable);	// Create an address space,
					// initializing it with the program
					// stored in the file "executable"
    ~AddrSpace();			// De-allocate an address space

    void InitRegisters();		// Initialize user-level CPU registers,
					// before jumping to user code

	int GetLocation(int vpn) { return location[vpn]; }

    void SaveState();			// Save/restore address space-specific
    void RestoreState();		// info on a context switch
    Table fileTable;			// Table of openfiles
#ifdef CHANGED
	int AllocateStack();
	int Get_Top_Of_Stack() { return numPages; }
	void DeallocateStack(int, int);
	int ConvertVPN(int vpn) { return pageTable[vpn].physicalPage; }
	TranslationEntry GetEntry(int vpn) { return pageTable[vpn]; }
	void FreeSwap();
	void MovedToSwap(int,int);
	void LoadFromExec(int,int);
	void LoadFromSwap(int,int);
	void InitializeStack(int vpn);
	void Evict(int vpn);
	bool isDirty(int vpn) { return pageTable[vpn].dirty; }
	int isMaxSize() { return maxSize; }

#endif

 private:
    TranslationEntry *pageTable;	// Assume linear page table translation
					// for now!
    unsigned int numPages;		// Number of pages in the virtual 
#ifdef CHANGED					// address space
	int* swapFileLoc;
	int* location; // 0=main memory, 1=executable (not swap), 2=swap, 3 = uninit/stack
	int* execLocation;
	int codeStart;
	int maxSize;
	OpenFile* exec;
	Lock* memoryAccessLock; // Lock for accessing main memory to prevent processes from allocating to main memory at locations
							// identified during the allocation process

#endif
};

#endif // ADDRSPACE_H
